﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using DevFx.FrameWork.Data;
using DevFx.FrameWork.Resources;
using DevFx.FrameWork.Exception;

namespace DevFx.FrameWork.Trans
{
    public class Transaction
    {
        #region 私有属性
        private DbConnection conn;
        private DbTransaction dbTrans;
        #endregion
        #region 公共属性
        /// <summary>
        /// 当前处于事务中
        /// </summary>
        public bool InTrans
        {
            get;
            set;
        }
        /// <summary>
        /// 数据库连接是否打开
        /// </summary>
        public bool IsOpen
        {
            get;
            set;
        }
        /// <summary>
        /// 是否打开了DataReader读取器，并且正在读取数据
        /// </summary>
        public bool IsReading
        {
            get;
            set;
        }
        public DbConnection DbConnection
        {
            get { return this.conn; }
        }

        public DbTransaction DbTrans
        {
            get { return this.dbTrans; }
        }
        #endregion
        /// <summary>
        /// 打开数据库
        /// </summary>
        /// <param name="isPrepareOpen">是否以准备打开数据库的方式打开</param>
        /// <remarks>准备方式打开数据库，其实并没有真的打开数据库，而是在执行第一条sql语句时，系统自动打开数据库连接</remarks>
        public void OpenDatabase()
        {
            if (!IsOpen)
            {
                lock (this)
                {
                    if (!IsOpen)
                    {
                        try
                        {
                            try
                            {
                                conn = DbHelper.CreateEFConnection();
                                conn.Open();
                                IsOpen = true;
                            }
                            catch (FrameException ex)
                            {
                                //数据库连接打开失败，抛出错误异常，并且处理数据库连接打开失败事件
                                string message = string.Format(null, FrameworkResources.OpenConnection_Failed, ex.Message);
                                FrameException exception = new FrameException(message, ex);
                                throw exception;
                            }
                        }
                        catch (FrameException ex)
                        {
                            //数据库打开成功的后处理事件中发生异常
                            string message = string.Format(null, FrameworkResources.Connection_OpenedEvent_Error, ex.Message);
                            throw new FrameException(message, ex);
                        }
                    }
                }
            }
        }

        public void BeginTrans()
        {
            //数据库没有打开，但处于准备打开状态
            if (!IsOpen)
                OpenDatabase();
            if (!IsOpen)
                throw new FrameException(FrameworkResources.Transation_NoOpenDatabase);
            if (!InTrans)
            {
                lock (this)
                {
                    if (!InTrans)
                    {
                        try
                        {
                            dbTrans = DbConnection.BeginTransaction();
                            InTrans = true;
                        }
                        catch (System.Exception ex)
                        {
                            string message = string.Format(null, FrameworkResources.OpenTransation_Failed, ex.Message);
                            throw new FrameException(message, ex);
                        }

                    }
                }
            }
        }
        //提交事务
        public void CommitTrans()
        {
            if (InTrans)
            {
                lock (this)
                {
                    if (InTrans)
                    {
                        try
                        {
                            dbTrans.Commit();
                            dbTrans = null;
                            InTrans = false;
                        }
                        catch (System.Exception ex)
                        {
                            string message = string.Format(null, FrameworkResources.CommitTransation_Failed, ex.Message);
                            throw new FrameException(message, ex);
                        }

                    }
                }
            }
        }
        //回滚事务
        public void RollBack()
        {
            if (InTrans)
            {
                lock (this)
                {
                    if (InTrans)
                    {
                        try
                        {
                            dbTrans.Rollback();
                            dbTrans = null;
                            InTrans = false;
                        }
                        catch (System.Exception ex)
                        {
                            string message = string.Format(null, FrameworkResources.RollbackTransation_Failed, ex.Message);
                            throw new FrameException(message, ex);
                        }

                    }
                }
            }
        }
        /// <summary>
        /// 关闭数据库连接
        /// </summary>
        public void CloseDatabase()
        {

            if (IsOpen)
            {
                lock (this)
                {
                    if (IsOpen)
                    {
                        try
                        {
                            conn.Close();
                            conn.Dispose();
                            IsOpen = false;
                            IsReading = false;
                        }
                        catch (System.Exception ex)
                        {
                            string message = string.Format(null, FrameworkResources.CloseConnection_Failed, ex.Message);
                            throw new FrameException(message, ex);
                        }
                    }
                }
            }
        }
    }
}
